package net.obxlabs.tweetpad;

import java.awt.*;
import net.nexttext.*;
import net.nexttext.behaviour.control.*;
import net.nexttext.behaviour.dform.*;
import net.nexttext.behaviour.physics.*;
import net.nexttext.behaviour.standard.*;
import net.nexttext.processing.*;
import net.obxlabs.tweetpad.behaviour.*;
import net.obxlabs.tweetpad.stats.*;
import net.silentlycrashing.gestures.*;
import net.silentlycrashing.gestures.preset.*;
import processing.core.*;

/**
 * The entry point into tweetPad.
 */
/* $Id$ */
public class Sketchpad extends PApplet {
	public final static String PLAY_KEY = "PlayKey";
	public final static String REORDER_KEY = "ReorderKey";
	public final static String KILL_KEY = "KillKey";
	
	private Book book;
	private Maker maker;
	private Font font;
	
	private GestureAnalyzer brain;
	private PostGestureListener cwEar;
	private PostGestureListener ccwEar;
	private ConcurrentGestureListener shakeEar;
	private PostGestureListener backEar;
	
	private Blob blob;
	
	private Mailman mailman;
	private ThumbStrip thumbStrip;
	private Counter counter;
	
	boolean recordPDF;
	boolean recordPNG;
	boolean recordSVG;
	
	public void setup() {
		size(1024, 768);
		frameRate(60);
        smooth();
        
        // build the book
        book = new Book(this);
        maker = new Maker(book);
        book.toBuilder = maker;
        
        // load and set the counter font
        font = book.loadFont("resources/bluehigh.ttf");
        book.textFont(font, 12);
        
        counter = new Counter(this, book);
        mailman = new Mailman(this);
        thumbStrip = new ThumbStrip(this, mailman, counter);
        blob = new Blob(this, width-70, 70, 40);
        
        // create the gesture listeners
        brain = new MouseGestureAnalyzer(this, RIGHT);
        cwEar = new PostCWTwirlListener(this, brain);
        ccwEar = new PostCCWTwirlListener(this, brain);
        shakeEar = new ConcurrentGestureListener(this, brain, "L?(RL){6,}R?");
        backEar = new PostGestureListener(this, brain, "^L$");
        
        // create the fantastic behaviour
    				UnlinkingKey playKey = new UnlinkingKey(PLAY_KEY);
        			FollowThumb followThumb = new FollowThumb();
        		OnClickOver onFirstPress = new OnClickOver(playKey, followThumb);
        	Level levelFirstPress = new Level(3, onFirstPress);
            		EaseIntoPlay easeIntoPlay = new EaseIntoPlay();
	            				Move move = new Move(0.01f, 0.01f);
										MoveOver moveOverMouse = new MoveOver(Book.mouse);
									Repeat followMouse = new Repeat(moveOverMouse, 0);
	        							StayInWindow stayInWindow = new StayInWindow(this);
	        									Key pullAndKillKey = new Key(KILL_KEY);
	        								Repeat repeatKillKey = new Repeat(pullAndKillKey, 0);
	        							OnDrop onDropInBlob = new OnDrop(repeatKillKey, blob.getBounds());
	        							MouseInertia mouseInertia = new MouseInertia(this, ProcessingMouse.BUTTON1, 0.1f);
	        						Multiplexer inertiaAndDropInBlob = new Multiplexer();
	        						inertiaAndDropInBlob.add(stayInWindow);
	        						inertiaAndDropInBlob.add(onDropInBlob);
	        						inertiaAndDropInBlob.add(mouseInertia);
	        					Throw throwAround = new Throw(ProcessingMouse.BUTTON1, followMouse, inertiaAndDropInBlob);
	        					moveOverMouse.setTarget(throwAround);
	        							Pull pullIntoBlob = new Pull(blob, 10, 2);
	        								Kill kill = new Kill();
	        							Delay delayKill = new Delay(kill, 16);
	        						Multiplexer pullAndKill = new Multiplexer();
	        						pullAndKill.add(pullIntoBlob);
	        						pullAndKill.add(delayKill);
	        					Gate pullAndKillGate = new Gate(KILL_KEY, pullAndKill);
	        				Multiplexer moveAndThrowAround = new Multiplexer();
	        				moveAndThrowAround.add(move);
	        				moveAndThrowAround.add(throwAround);
	        				moveAndThrowAround.add(pullAndKillGate);
        				Level levelThrowAround = new Level(3, moveAndThrowAround);
        							Swap swap = new Swap(book, maker);  // no leveling! Swap levels itself
	    						OnPostGesture onCWTwirl = new OnPostGesture(cwEar, swap);
	    			        Repeat listenForCWTwirl = new Repeat(onCWTwirl, 0);
	    			        		Unswap unswap = new Unswap(book, maker);  // no leveling! Swap levels itself
	    			        	OnPostGesture onCCWTwirl = new OnPostGesture(ccwEar, unswap);
	    			        Repeat listenForCCWTwirl = new Repeat(onCCWTwirl, 0);
    			        Multiplexer listenForTwirls = new Multiplexer();
    			        listenForTwirls.add(listenForCWTwirl);
    			        listenForTwirls.add(listenForCCWTwirl);
			    			        			Shuffle shuffle = new Shuffle();
			    			        		Repeat repeatShuffle = new Repeat(shuffle, 0);
			    			        		//Flicker flicker = new Flicker();
		    			        		Multiplexer shuffleAndFlicker = new Multiplexer();
		    			        		shuffleAndFlicker.add(repeatShuffle);
		    			        		//shuffleAndFlicker.add(flicker);
		    			        			ColorizeBack colorizeBack = new ColorizeBack();
		    			        		Repeat repeatColorizeBack = new Repeat(colorizeBack, 0);
		    			        	OnConcurrentGesture onShake = new OnConcurrentGesture(shakeEar, shuffleAndFlicker, repeatColorizeBack);
			    			        	Key reorderKey = new Key(REORDER_KEY);        		
			    			        OnPostGesture onBack = new OnPostGesture(backEar, reorderKey);
			    			        	ReorderSiblings reorder = new ReorderSiblings();  // no leveling! Reorder levels itself
			    			        Gate reorderGate = new Gate(REORDER_KEY, reorder);
			    			    Multiplexer shakeAndReorder = new Multiplexer();
			    			    shakeAndReorder.add(onShake);
			    			    shakeAndReorder.add(onBack);
			    			    shakeAndReorder.add(reorderGate);
		    			    Repeat repeatShakeAndReorder = new Repeat(shakeAndReorder, 0);
    			        Level levelShakeAndBack = new Level(2, repeatShakeAndReorder);
    			        				//BreakApart breakApart = new BreakApart(2);
    			        			//Delay breakApartDelay = new Delay(breakApart, 2);
    			        		//EdgeCollide edgeCollide = new EdgeCollide(this, EdgeCollide.RIGHT, breakApartDelay);
    			        	//Repeat repeatEdgeCollide = new Repeat(edgeCollide, 0);
    			        //Level levelCollide = new Level(3, repeatEdgeCollide);
        			Multiplexer play = new Multiplexer();
        			play.add(levelThrowAround);
    				play.add(listenForTwirls);
    				play.add(levelShakeAndBack);
        			//play.add(levelCollide);
        			//Level levelPlay = new Level(3, play);
        			//breakApart.setLevel(levelForPlay);
        		Chain easeAndPlay = new Chain();
            	easeAndPlay.add(easeIntoPlay);
            	easeAndPlay.add(play);   			
        	Gate playGate = new Gate(PLAY_KEY, easeAndPlay, true);
        Multiplexer mother = new Multiplexer();
        mother.add(levelFirstPress);
        mother.add(playGate);
        
        book.addGlyphBehaviour(mother.makeBehaviour());
        
        // load and set the main font
        font = book.loadFont("resources/Cyberbit.ttf");
        book.textFont(font, 12);
        
        mailman.start("Twitter Mailman");
        thumbStrip.start("Twitter Strip");
	}
	
	public void draw() {
		background(255);
		thumbStrip.draw();
		fill(255);
		noStroke();
		rect(0, height-40, width, height);
		counter.draw();
		blob.draw();
		book.stepAndDraw();
	}
	
	public void mousePressed() {
		if (mouseButton == CENTER) {
			counter.reset();
		}
	}
    
    /**
     * Runs the applet as an application.
     * <p>This is required to run in "present" mode.</p>
     *
     * @param args runtime arguments (not used here)
     */
    static public void main(String args[]) {
        PApplet.main(new String[] {  
            "--present",
            "--bgcolor=#000000",
            "--present-stop-color=#000000",
            "net.obxlabs.tweetpad.Sketchpad"
        });
    } 
    
    public Book getBook() { return book; }
    public Maker getMaker() { return maker; }
}
